﻿/*
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//#define WORDMAX 3
//#define WORDMAX 4
#define WORDMAX 111105
*/

/*
struct dicts
{
	char* word;//单词 4
	char* trans;//翻译 4
};
typedef struct dicts dic;
*/

//22.定义全局变量p；-->现在不用一级指针了，要用二级指针传递地址了；
//dic* p;
//21.定义成函数，打开文件，存储数据；
//void ReadFile()

#include "Dict.h"

void ReadFile(dic** p)
{
	//15.查询一下，dict.txt中，一共多少个单词；测试文件大小；
	/*
	FILE* fpD = fopen("E:\\file\\dict.txt", "r");
	if (!fpD)
	{
		return -1;
	}
	char arr[1024];
	int count = 0;
	while (!feof(fpD))
	{
		fgets(arr, 1024, fpD);
		count++;
	}

	fclose(fpD);
	printf("16.dict.txt中一共 %d 行，则单词总数为：%d\n", count, count / 2);//222209 111104
	*/

	//1.开辟堆空间，存放词典结构体指针变量；
	//dic* p = (dic*)malloc(sizeof(dic) * WORDMAX);
	//p = (dic*)malloc(sizeof(dic) * WORDMAX);

	//31.二级指针的地址指向一级指针，开辟堆内存空间；这里的p为dic**，*p为一级指针，为*p开辟堆内存空间；
	* p = (dic*)malloc(sizeof(dic) * WORDMAX);

	//2.读取文件内容；
	//FILE* fp = fopen("E:\\file\\dictTest.txt", "r");
	FILE* fp = fopen("E:\\file\\dict.txt", "r");
	if (!fp)
	{
		return -1;
	}

	int i = 0;
	//3.读取到的一行内容；
	char buf[1024];
	while (!feof(fp))
	{
		memset(buf, 0, 1024);
		fgets(buf, 1024, fp);
		//4.开启堆内存空间，存放单词；strlen求出buf的有效长度，不包括\n，所以要加1；
		/*
		p[i].word = (char*)malloc(strlen(buf) + 1);
		memset(p[i].word, 0, strlen(buf) + 1);
		//strcpy(p[i].word, buf);
		//14.存储单词，去掉#，即从buf[1]开始存；
		strcpy(p[i].word, &buf[1]);
		*/

		(*p + i)->word = (char*)malloc(strlen(buf) + 1);
		memset((*p + i)->word, 0, strlen(buf) + 1);
		strcpy((*p + i)->word, &buf[1]);

		memset(buf, 0, 1024);
		fgets(buf, 1024, fp);
		/*
		p[i].trans = (char*)malloc(strlen(buf) + 1);
		memset(p[i].trans, 0, strlen(buf) + 1);
		strcpy(p[i].trans, buf);
		*/

		(*p + i)->trans = (char*)malloc(strlen(buf) + 1);
		memset((*p + i)->trans, 0, strlen(buf) + 1);
		strcpy((*p + i)->trans, buf);

		//printf("==============5.读取到的单词和解释：==================\n");
		//6.输出的单词和解释，都自带\n换行符；
		//printf("%s", p[i].word);
		//printf("%s", p[i].trans);

		i++;
	}

	fclose(fp);
}

//23.文件查找；ch，输入的单词；content，对应的单词翻译；
//int SearchWord(char* ch, char* content)
int SearchWord(char* ch, char* content, dic* p)
{
	for (int i = 0; i < WORDMAX; i++)
	{
		//11.只比较输入单词的有效长度，即apple只比较这5个字母，后面的\n不管；要以输入的字符串ch作为匹配标准，hello匹配走一圈；
		//if (!strncmp(ch, p[i].word, strlen(ch)))
			//17.我上面的写法是正确的，现在要换成下面这种比对方式；strlen(p[i].word) - 1，意思是字符串减去\n；
			//然而还是出错了，因为p[i].world为匹配标准，就是以最先出现的单词来匹配。即hello会匹配到he，这就出错了。
			//if (!strncmp(ch, p[i].word, strlen(p[i].word) - 1))

		//20.改成上面的fgets(ch,1024,stdin)后，就不用有限比较了，直接比较就可以了；
		if (!strcmp(ch, p[i].word))
		{
			//printf("%s", p[i].trans);
			//flag = 1;
			//break;
			//34.找到单词，返回1；
			strcpy(content, p[i].trans);
			return 1;
		}
	}
	return 0;
}

//24.释放堆空间；
void clear(dic* p)
{
	//13.释放堆内存空间；
	for (int i = 0; i < WORDMAX; i++)
	{
		free(p[i].word);
		free(p[i].trans);
	}
	free(p);
}

//main172：案例：快译通文本文件实现英汉字典
int main172()
{
	//30.不用全局变量p了，用二级指针来表示地址；
	dic* p;

	//27.读取文件；
	//ReadFile();
	ReadFile(&p);

	//25.单词翻译，是p[i].trans；
	char content[1024];

	//7.查询单词；
	char ch[1024];
	//9.putchar('\n')和printf('\n')一样，都是为了换行；puts()，输出一个字符串，并换行，自动加上【\n】；
	//putchar('\n');

	//8.gets(),获取一个字符串，可以有空格，不会获取到\n；getchar()，获取一个字符，其实就是为了接收一个\n换行符，这里enter为换行符；
	//gets(ch);
	//18.若是以ch为匹配标准，其实加不加\n都可以，反正匹配字典库的字符串，只要ch的长度就行了；
	//strcat(ch, "\n");
	//19.使用fgets()接收字符串，会在字符串末尾自动加上\n换行符；=gets()+strcat()；
	//fgets(ch, 1024, stdin);

	//10.scanf获取字符串，%s不能有空格，%[^\n]接收非【\n】之前的字符（可以接收hello world）；
	//scanf("%s", &ch);
	//scanf("%[^\n]", &ch);

	/*
	int flag = 0;
	for (int i = 0; i < WORDMAX; i++)
	{
		//11.只比较输入单词的有效长度，即apple只比较这5个字母，后面的\n不管；要以输入的字符串ch作为匹配标准，hello匹配走一圈；
		//if (!strncmp(ch, p[i].word, strlen(ch)))
			//17.我上面的写法是正确的，现在要换成下面这种比对方式；strlen(p[i].word) - 1，意思是字符串减去\n；
			//然而还是出错了，因为p[i].world为匹配标准，就是以最先出现的单词来匹配。即hello会匹配到he，这就出错了。
			//if (!strncmp(ch, p[i].word, strlen(p[i].word) - 1))

		//20.改成上面的fgets(ch,1024,stdin)后，就不用有限比较了，直接比较就可以了；
		if (!strcmp(ch, p[i].word))
		{
			printf("%s", p[i].trans);
			flag = 1;
			break;
		}
	}

	if (flag == 0)
	{
		printf("12.未找到该单词的解释！\n");
	}
	*/

	//28.结果判断；
	//int flag = SearchWord(ch, content);
	//32.查找单词时，不需要对内容进行操作，就使用一级指针dic* p就可以。这里的形参和实参不是一个p；
	/*
	int flag = SearchWord(ch, content, p);

	if (flag)
	{
		printf("26.该单词对应的解释为：\n%s\n", content);
	}
	else
	{
		printf("12.未找到该单词的解释！\n");
	}
	*/

	printf("37.请输入要查询的单词，按回车键结束：\n");

	//35.死循环查找单词翻译；
	while (1)
	{
		fgets(ch, 1024, stdin);

		//36.结束条件，退出循环；
		if (!strncmp("comm=exit", ch, 9))
		{
			break;
		}

		int flag = SearchWord(ch, content, p);
		if (flag)
		{
			printf("26.该单词对应的解释为：\n%s\n", content);
		}
		else
		{
			printf("12.未找到该单词的解释！\n\n");
		}
	}

	/*37.请输入要查询的单词，按回车键结束：
	hello
	26.该单词对应的解释为：
	Trans:int. 喂;哈罗

	hello world
	12.未找到该单词的解释！

	goodbye
	26.该单词对应的解释为：
	Trans:int. 再见

	comm=exit
	*/


	//29.释放堆空间；
	//clear();

	//33.释放堆内存时，也是同样的道理，传递一级指针dic* p就可以；
	//上面ReadFile()传递的是二级指针&p，其实还是给一级指针p开辟堆空间，这里释放当然还是p；
	//ReadFile()的特殊就在于，它里面p不是全局变量，而是通过一级指针p的地址来传递参数的。
	clear(p);

	//system("pause");
	return EXIT_SUCCESS;
}